import { Base64 } from "js-base64"
import pako from "pako"

/**
 * 假设原始数据是一个对象 {name: "John", age: 30}，经过以下步骤处理：
 * 原始数据 → JSON 字符串：'{"name":"John","age":30}'
 * Base64 编码：'eyJuYW1lIjoiSm9obiIsImFnZSI6MzB9'
 * Gzip 压缩 → 二进制数据
 * Base64 编码压缩后的数据（假设结果为 "H4sIAAAAAAC..."）
 * 当这个 "H4sIAAAAAAC..." 传入 unzip 函数时：
 * Base64 解码压缩数据
 * Gzip 解压得到 'eyJuYW1lIjoiSm9obiIsImFnZSI6MzB9'
 * Base64 解码得到 '{"name":"John","age":30}'
 * JSON 解析得到对象 {name: "John", age: 30}
 */

// 解压
export function unzip(b64Data: string) {
    // 将Base64编码的字符串解码为二进制字符串   "SGVsbG8=" → "Hello"
    const strData = Base64.atob(b64Data)
    // 将其转为ascii码数组   "Hello" → [72, 101, 108, 108, 111]
    const charData = strData.split("").map(x => x.charCodeAt(0))

    // 将字符代码数组转换为 Uint8Array 类型，这是 pako 库需要的输入格式  [72, 101, 108, 108, 111] → Uint8Array(5) [72, 101, 108, 108, 111]
    const binData = new Uint8Array(charData)
    // 使用 pako 库的 ungzip 方法解压数据 ,返回的是解压后的 Uint8Array 数据
    const data = pako.ungzip(binData)

    // 分块处理大数据（防止内存溢出）
    // 将大数据分成 8KB 的块进行处理，避免一次性处理大数组导致内存溢出
    // 使用 String.fromCharCode.apply 将 Uint8Array 转换为字符串
    let str = ""
    const chunk = 8 * 1024 // 8KB 的块大小
    let i
    for (i = 0; i < data.length / chunk; i++) {
        str += String.fromCharCode.apply(null, Array.from(data.slice(i * chunk, (i + 1) * chunk)))
    }
    str += String.fromCharCode.apply(null, Array.from(data.slice(i * chunk)))

    // 对解压后的字符串再进行 Base64 解码    "SGVsbG8=" → "Hello"
    const unzipStr = Base64.decode(str)

    let result: any
    try {
        // 将结果解析为 JSON 对象
        result = JSON.parse(unzipStr)
    } catch (error: any) {
        if (/Unexpected token o in JSON at position 0/.test(error)) {
            // 如果解析失败（比如原始数据不是 JSON），则直接返回字符串
            result = unzipStr
        }
    }
    return Array.isArray(result) ? result : [result]
}

// export function unzip(b64Data: string): any {
//     try {
//         // 将 Base64 字符串解码为二进制数据
//         const binData = Base64.toUint8Array(b64Data)

//         // 使用 pako 解压数据
//         const decompressedData = pako.ungzip(binData)

//         // 将解压后的二进制数据转换为字符串
//         const strData = new TextDecoder().decode(decompressedData)

//         // 将字符串解析为 JSON
//         const result = JSON.parse(strData)

//         return result
//     } catch (error) {
//         console.error("解压数据失败", error)
//         throw new Error("解压数据失败")
//     }
// }

// export function unzip(b64Data: string) {
//     try {
//         const binData = Base64.toUint8Array(b64Data)
//         const decompressedData = pako.ungzip(binData)
//         // 将解压后的二进制数据转换为字符串
//         const strData = new TextDecoder().decode(decompressedData)
//         // 将字符串解析为 JSON
//         const result = JSON.parse(strData)
//         return result
//     } catch (error) {
//         console.error("解压数据失败", error)
//         throw new Error("解压数据失败")
//     }
// }
